package com.yao.sdk.encrypt;

import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * Created by Administrator on 2016/7/15.
 */
public class Encrypt {
    static final String CHECK_AES="AZCwerusdfoIPLMK";
    static final String AES_IV="b2d799159b86715cf7efeff0f734c4f9"; //AES加密向量
    private String AESKey;//AES加密KEY
    static final String MD5_KEY="mh#@md~!2ert";
    static final char[] CHAR_ARRAY = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I','J','K',
            'L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','0','1','2','3','4'
            ,'5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o'
            ,'p','q','r','s','t','u','v','w','x','y','z'};
    private int aseKeyLength;

    public static class MapValueComparator implements Comparator<Map.Entry<String, String>> {

        @Override
        public int compare(Map.Entry<String, String> me1, Map.Entry<String, String> me2) {

            return me1.getKey().compareTo(me2.getKey());
        }
    }
    /**
     * 使用 Map按value进行排序
     * @return
     */
    public static Map<String, String> sortMapByKey(Map<String, String> oriMap) {
        if (oriMap == null || oriMap.isEmpty()) {
            return new HashMap<>();
        }
        Map<String, String> sortedMap = new LinkedHashMap<String, String>();
        List<Map.Entry<String, String>> entryList = new ArrayList<Map.Entry<String, String>>(
                oriMap.entrySet());
        Collections.sort(entryList, new MapValueComparator());

        Iterator<Map.Entry<String, String>> iter = entryList.iterator();
        Map.Entry<String, String> tmpEntry = null;
        while (iter.hasNext()) {
            tmpEntry = iter.next();
            sortedMap.put(tmpEntry.getKey(), tmpEntry.getValue());
        }
        return sortedMap;
    }
    public String toEncrppt(Map<String,String> paramsMap,String token){
        if (token!=null){
            paramsMap.put("_t",token);
        }
        paramsMap= sortMapByKey(paramsMap);//排序
        String md5Key=getMd5Key(paramsMap);
        paramsMap.put("_k",md5Key);

        AESKey=getASEKey();
        AES ase=new AES();
        String aseResult=null;
        try {
            aseResult=ase.encrypt(AES_IV,AESKey,map2Json(paramsMap));
        } catch (GeneralSecurityException e) {
            e.printStackTrace();
        }
//        Log.e("zwj","aseResult="+aseResult);
//        Log.e("zwj","aseResult_length="+aseResult.length());
        //将ASEKey拆开插入ASE加密后的结果
        int insertPos=aseResult.length()/aseKeyLength;
//        Log.e("zwj","insertPos="+insertPos);
        StringBuffer resultBuffer=new StringBuffer(aseResult);
        char[] aseKeyChar=AESKey.toCharArray();
        int num=0;
        for (int i = 0; i <aseKeyLength ; i++) {
            int position=insertPos*(i+1);
            resultBuffer.insert(position,aseKeyChar[i]);
        }
        //结果首部插入CHECK_AES中位置为aseKeyLength的char
        resultBuffer.insert(0,CHECK_AES.toCharArray()[aseKeyLength]);

        return resultBuffer.toString();
    }
    public String toDecryption(String content){
        if (content==null)
            return null;
        AES aes=new AES();
        try {
            String result=aes.decrypt(AES_IV,"4047f1ec64fa6cd42a3273f366053648",content);
//            Log.e("zwj","......解密后="+result);
            return  result;
        } catch (GeneralSecurityException e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 将基本参数拼接做MD5加密，加上MD5_KEY再次加密
     */
    private String getMd5Key(Map<String,String> paramMap){
        String paramString=getParamString(paramMap);
        return MD5.getMD5Str(MD5.getMD5Str(paramString)+MD5_KEY);

    }
    /**
     *拼接map中的参数
     */
    public String getParamString(Map<String,String> paramMap){
        if (paramMap!=null){
        StringBuffer paramString=new StringBuffer();
        for (Map.Entry<String, String> entry : paramMap.entrySet()) {
            paramString.append(entry.getKey());
            paramString.append(entry.getValue());
        }
//        Log.e("zwj",paramString.toString());

        return paramString.toString();
        }else {
            return "";
        }
    }

    public static String map2Json(Map<String,String> map){
        StringBuffer buffer=new StringBuffer();
        buffer.append("{");
        int position=0;
        for (Map.Entry<String, String> entry : map.entrySet()) {
            buffer.append("\""+entry.getKey()+"\":\""+entry.getValue()+"\"");
            position++;
            if (position!=map.size()){
                buffer.append(",");
            };
        }
        buffer.append("}");
//        Log.e("zwj","json="+buffer.toString());
        return buffer.toString();
    }
    /**
     * 生成aseKey:先生成一个5到CHECK_AES长度-1范围内的随机数，再到生成该数个数的CHAR_ARRAY数组随机字符，作为asekey
     */
    private String getASEKey(){
        Random random=new Random();
        aseKeyLength=random.nextInt(CHECK_AES.length()-5)+5;
//        aseKeyLength=15;
//        Log.e("zwj","aseKeyLength="+aseKeyLength);
        StringBuffer ASEKeyBuffer=new StringBuffer();
        for (int i = 0; i <aseKeyLength; i++) {
            char c=CHAR_ARRAY[random.nextInt(CHAR_ARRAY.length)];
            ASEKeyBuffer.append(c);
        }
        String ASEKey=ASEKeyBuffer.toString();
//        ASEKey="4Wl1Uk7E8xvXhs7";
//        Log.e("zwj","ASEKey="+ASEKey);
        return ASEKey;
    }
}
